package cn.iocoder.yudao.module.tms.service.bandinfo;

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.tms.controller.admin.bandinfo.vo.BandOrderPageReqVO;
import cn.iocoder.yudao.module.tms.controller.admin.bandinfo.vo.BandOrderSaveReqVO;
import cn.iocoder.yudao.module.tms.dal.dataobject.bandinfo.BandInfoDO;
import cn.iocoder.yudao.module.tms.dal.dataobject.bandinfo.BandOrderDO;
import cn.iocoder.yudao.module.tms.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.tms.dal.mysql.bandinfo.BandOrderMapper;
import cn.iocoder.yudao.module.tms.dal.mysql.order.OrderMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import jakarta.annotation.Resource;

import java.util.Collection;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.tms.enums.ErrorCodeConstants.BAND_ORDER_NOT_EXISTS;
import static cn.iocoder.yudao.module.tms.enums.ErrorCodeConstants.BAND_ORDER_DUPLICATE;

/**
 * Band 与订单关联 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class BandOrderServiceImpl implements BandOrderService {

    @Resource
    private BandOrderMapper bandOrderMapper;

    @Resource
    private BandInfoService bandInfoService;

    @Resource
    private OrderMapper orderMapper;

    @Override
    public Long createBandOrder(BandOrderSaveReqVO createReqVO) {
        // 唯一性校验：Band 与 Order 一一对应
        validateUniqueBinding(createReqVO.getBandCode(), createReqVO.getOrderCode(), null);
        BandOrderDO bandOrder = BeanUtils.toBean(createReqVO, BandOrderDO.class);
        bandOrderMapper.insert(bandOrder);
        return bandOrder.getId();
    }

    @Override
    public void updateBandOrder(BandOrderSaveReqVO updateReqVO) {
        // 校验存在
        validateBandOrderExists(updateReqVO.getId());
        // 唯一性校验：Band 与 Order 一一对应（排除自身ID）
        validateUniqueBinding(updateReqVO.getBandCode(), updateReqVO.getOrderCode(), updateReqVO.getId());
        // 更新
        BandOrderDO updateObj = BeanUtils.toBean(updateReqVO, BandOrderDO.class);
        bandOrderMapper.updateById(updateObj);
    }

    @Override
    public void deleteBandOrder(Long id) {
        // 校验存在
        validateBandOrderExists(id);
        // 删除
        bandOrderMapper.deleteById(id);
    }

    private void validateBandOrderExists(Long id) {
        if (bandOrderMapper.selectById(id) == null) {
            throw exception(BAND_ORDER_NOT_EXISTS);
        }
    }

    @Override
    public BandOrderDO getBandOrder(Long id) {
        return bandOrderMapper.selectById(id);
    }

    @Override
    public List<BandOrderDO> getBandOrderList(Collection<Long> ids) {
        return bandOrderMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<BandOrderDO> getBandOrderPage(BandOrderPageReqVO pageReqVO) {
        return bandOrderMapper.selectPage(pageReqVO);
    }

    @Override
    public PageResult<OrderDO> getUnboundOrderPage(String bandCode, String orderKeyword, PageParam pageReqVO) {
        // 查询所有已绑定的订单 Code 列表（全局未绑定逻辑，不再按 bandCode 限制）
        List<String> boundOrderCodes = bandOrderMapper.selectList(new LambdaQueryWrapperX<>())
                .stream()
                .map(BandOrderDO::getOrderCode)
                .filter(java.util.Objects::nonNull) // 过滤掉 null 值
                .toList();

        // 查询未绑定的订单（排除已绑定的 clientNumber）
        LambdaQueryWrapper<OrderDO> queryWrapper = new LambdaQueryWrapper<OrderDO>()
                .notIn(CollectionUtil.isNotEmpty(boundOrderCodes), OrderDO::getClientNumber, boundOrderCodes)
                .orderByDesc(OrderDO::getId);

        // 添加订单关键字搜索条件
        if (orderKeyword != null && !orderKeyword.isEmpty()) {
            queryWrapper.and(wrapper -> wrapper
                    .like(OrderDO::getEnglishName, orderKeyword)
                    .or()
                    .like(OrderDO::getChineseName, orderKeyword));
        }

        return orderMapper.selectPage(pageReqVO, queryWrapper);
    }

    @Override
    public cn.iocoder.yudao.module.tms.controller.admin.bandinfo.vo.BandOrderStatsRespVO getBandOrderStats(String bandCode) {
        Long count = bandOrderMapper.selectCountByBandCode(bandCode);
        java.math.BigDecimal usedAmount = bandOrderMapper.selectSumAmountByBandCode(bandCode);
        BandInfoDO bandInfoByCode = bandInfoService.getBandInfoByCode(bandCode);
        cn.iocoder.yudao.module.tms.controller.admin.bandinfo.vo.BandOrderStatsRespVO resp = new cn.iocoder.yudao.module.tms.controller.admin.bandinfo.vo.BandOrderStatsRespVO();
        resp.setBandCode(bandCode);
        resp.setOrderCount(count);
        resp.setTotalAmount(bandInfoByCode.getTotalAmount());
        resp.setUsedAmount(usedAmount);
        return resp;
    }

    /**
     * 校验 Band 与 Order 的一一对应：
     * - 同一 Band 只能绑定一个 Order
     * - 同一 Order 只能绑定一个 Band
     * 若发现除自身之外已有绑定，则抛出重复绑定异常
     */
    private void validateUniqueBinding(String bandCode, String orderCode, Long excludeId) {
        // 检查 Band 是否已绑定其他 Order
        LambdaQueryWrapperX<BandOrderDO> bandQuery = new LambdaQueryWrapperX<BandOrderDO>()
                .eq(BandOrderDO::getBandCode, bandCode).eq(BandOrderDO::getOrderCode, orderCode);
        if (excludeId != null) {
            bandQuery.ne(BandOrderDO::getId, excludeId);
        }
        BandOrderDO bandBound = bandOrderMapper.selectOne(bandQuery);
        if (bandBound != null) {
            throw exception(BAND_ORDER_DUPLICATE);
        }

    }

}